//
//  ZDAlertView.m
//  ZDAlertViewController
//
//  Created by Darker on 2017/3/9.
//  Copyright © 2017年 Darker. All rights reserved.
//

#import "ZDAlertView.h"

#pragma mark - Private
/**
 *  取消按钮默认标题
 */
static NSString *const ZDCancelButtonTitleDefault = @"确定";
/**
 *  toast默认展示时间，当设置为0时，用该值
 */
static NSTimeInterval const ZDToastShowDurationDefault = 1.0f;
/**
 *  alertView子视图key
 */
static NSString *const ZDAlertViewAccessoryViewKey = @"accessoryView";


#pragma mark - Public
//1.常规alert
void zd_showAlertTwoButton(NSString *title, NSString *message, NSString *cancelButtonTitle, ZDAlertClickBlock cancelBlock, NSString *otherButtonTitle, ZDAlertClickBlock otherBlock)
{
    zd_getSafeMainQueue(^{
        [ZDAlertView showAlertViewWithTitle:title message:message cancelButtonTitle:cancelButtonTitle otherButtonTitle:otherButtonTitle cancelButtonBlock:cancelBlock otherButtonBlock:otherBlock];
    });
}
void zd_showAlertOneButton(NSString *title, NSString *message, NSString *cancelButtonTitle, ZDAlertClickBlock cancelBlock)
{
    zd_showAlertTwoButton(title, message, cancelButtonTitle, cancelBlock, nil, NULL);
}
void zd_showAlertTitle(NSString *title)
{
    zd_showAlertTwoButton(title, nil, ZDCancelButtonTitleDefault, NULL, nil, NULL);
}
void zd_showAlertMessage(NSString *message)
{
    zd_showAlertTwoButton(@"", message, ZDCancelButtonTitleDefault, NULL, nil, NULL);
}
void zd_showAlertTitleMessage(NSString *title, NSString *message)
{
    zd_showAlertTwoButton(title, message, ZDCancelButtonTitleDefault, NULL, nil, NULL);
}

//2.无按钮toast
void zd_showToastTitleMessageDismiss(NSString *title, NSString *message, NSTimeInterval duration, ZDAlertClickBlock dismissCompletion)
{
    zd_getSafeMainQueue(^{
        [ZDAlertView showToastViewWithTitle:title message:message duration:duration dismissCompletion:dismissCompletion];
    });
}
void zd_showToastTitleDismiss(NSString *title, NSTimeInterval duration, ZDAlertClickBlock dismissCompletion)
{
    zd_showToastTitleMessageDismiss(title, nil, duration, dismissCompletion);
}
void zd_showToastMessageDismiss(NSString *message, NSTimeInterval duration, ZDAlertClickBlock dismissCompletion)
{
    zd_showToastTitleMessageDismiss(@"", message, duration, dismissCompletion);
}
void zd_showToastTitle(NSString *title, NSTimeInterval duration)
{
    zd_showToastTitleMessageDismiss(title, nil, duration, NULL);
}
void zd_showToastMessage(NSString *message, NSTimeInterval duration)
{
    zd_showToastTitleMessageDismiss(@"", message, duration, NULL);
}

//3.文字HUD
void zd_showTextHUDTitleMessage(NSString *title, NSString *message)
{
    zd_getSafeMainQueue(^{
        [ZDAlertView showTextHUDWithTitle:title message:message];
    });
}
void zd_showTextHUDTitle(NSString *title)
{
    zd_showTextHUDTitleMessage(title, nil);
}
void zd_showTextHUDMessage(NSString *message)
{
    zd_showTextHUDTitleMessage(@"", message);
}

//4.loadHUD
void zd_showLoadingHUDTitleMessage(NSString *title, NSString *message)
{
    zd_getSafeMainQueue(^{
        [ZDAlertView showLoadingHUDWithTitle:title message:message];
    });
}
void zd_showLoadingHUDTitle(NSString *title)
{
    zd_showLoadingHUDTitleMessage(title, nil);
}
void zd_showLoadingHUDMessage(NSString *message)
{
    zd_showLoadingHUDTitleMessage(@"", message);
}

//5.progressHUD
void zd_showProgressHUDTitleMessage(NSString *title, NSString *message)
{
    zd_getSafeMainQueue(^{
        [ZDAlertView showProgressHUDWithTitle:title message:message];
    });
}
void zd_showProgressHUDTitle(NSString *title)
{
    zd_showProgressHUDTitleMessage(title, nil);
}
void zd_showProgressHUDMessage(NSString *message)
{
    zd_showProgressHUDTitleMessage(@"", message);
}
void zd_setHUDProgress(float progress)
{
    [ZDAlertView setHUDProgress:progress];
}

//6.HUD公用
//成功状态
void zd_setHUDSuccessTitleMessage(NSString *title, NSString *message)
{
    zd_getSafeMainQueue(^{
        [ZDAlertView setHUDSuccessStateWithTitle:title message:message];
    });
}
void zd_setHUDSuccessTitle(NSString *title)
{
    zd_setHUDSuccessTitleMessage(title, nil);
}
void zd_setHUDSuccessMessage(NSString *message)
{
    zd_setHUDSuccessTitleMessage(@"", message);
}
//失败状态
void zd_setHUDFailTitleMessage(NSString *title, NSString *message)
{
    zd_getSafeMainQueue(^{
        [ZDAlertView setHUDFailStateWithTitle:title message:message];
    });
}
void zd_setHUDFailTitle(NSString *title)
{
    zd_setHUDFailTitleMessage(title, nil);
}
void zd_setHUDFailMessage(NSString *message)
{
    zd_setHUDFailTitleMessage(@"", message);
}
//关闭HUD
void zd_dismissHUD()
{
    zd_getSafeMainQueue(^{
        [ZDAlertView dismissHUD];
    });
}


#pragma mark - define
/**
 *  ZDAlertType
 */
typedef NS_ENUM(NSInteger, ZDAlertType) {
    ZDAlertTypeNormal,
    ZDAlertTypeToast,
    ZDAlertTypeHUD
};

/**
 *  ZDAlertHUDType
 */
typedef NS_ENUM(NSInteger, ZDAlertHUDType) {
    ZDAlertHUDTypeTextOnly,
    ZDAlertHUDTypeLoading,
    ZDAlertHUDTypeProgress
};

@interface ZDAlertView()<UIAlertViewDelegate>

//block
@property (nonatomic, copy) ZDAlertClickBlock buttonClickBlock;
@property (nonatomic, copy) ZDAlertClickBlock completionBlock;
//type
@property (nonatomic, assign) ZDAlertType alertType;
@property (nonatomic, assign) ZDAlertHUDType alertHUDType;
//HUD附件
@property (nonatomic, strong) UIActivityIndicatorView *indicatorView;
@property (nonatomic, strong) UIProgressView *progressView;

- (instancetype)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitle:(NSString *)otherButtonTitle, ... NS_REQUIRES_NIL_TERMINATION;


@end

@implementation ZDAlertView

#pragma mark - Init
- (instancetype)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitle:(NSString *)otherButtonTitle, ...
{
    self = [self initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitle, nil];
    if (!self) return nil;
    
    return self;
}

#pragma mark - shared
static ZDAlertView *__zd_commonHUD = nil;
+ (instancetype)sharedCommonHUDWithHUDType:(ZDAlertHUDType)HUDType
{
    if (__zd_commonHUD == nil)
    {
        __zd_commonHUD = [[ZDAlertView alloc] initWithTitle:nil message:nil cancelButtonTitle:nil otherButtonTitle:nil];
        //
        __zd_commonHUD.alertType = ZDAlertTypeHUD;
        __zd_commonHUD.alertHUDType = HUDType;
        
        switch (HUDType)
        {
            case ZDAlertHUDTypeTextOnly:
                break;
            case ZDAlertHUDTypeLoading:
            {
                //添加指示器
                UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
                indicatorView.color = [UIColor blackColor];
                [indicatorView startAnimating];
                __zd_commonHUD.indicatorView = indicatorView;
                //强制添加子视图
                if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
                {
                    [__zd_commonHUD setValue:indicatorView forKey:ZDAlertViewAccessoryViewKey];
                }
                else
                {
                    [__zd_commonHUD addSubview:indicatorView];
                }
                break;
            }
            case ZDAlertHUDTypeProgress:
            {
                //添加进度条
                UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
                progressView.progressTintColor = [UIColor blackColor];
                progressView.progress = 0.0;
                __zd_commonHUD.progressView = progressView;
                //强制添加子视图
                if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
                {
                    [__zd_commonHUD setValue:progressView forKey:ZDAlertViewAccessoryViewKey];
                }
                else
                {
                    [__zd_commonHUD addSubview:progressView];
                }
                break;
            }
        }
    }
    return __zd_commonHUD;
}
+ (ZDAlertView *)sharedCommonHUD
{
    return __zd_commonHUD;
}
+ (void)clearCommonHUD
{
    __zd_commonHUD = nil;
}

//重写setValue:forUndefinedKey:方法，处理不存在的key赋值，防止崩溃
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    NSLog(@"key: %@ 不存在", key);
}
- (id)valueForUndefinedKey:(NSString *)key
{
    NSLog(@"value: %@ 不存在", key);
    return nil;
}


#pragma mark - Methods
//1.常规alert
+ (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitle:(NSString *)otherButtonTitle cancelButtonBlock:(ZDAlertClickBlock)cancelBlock otherButtonBlock:(ZDAlertClickBlock)otherBlock
{
    if (!(title.length > 0) && message.length > 0) {
        title = @"";
    }
    ZDAlertView *alertView = [[ZDAlertView alloc] initWithTitle:title message:message cancelButtonTitle:cancelButtonTitle otherButtonTitle:otherButtonTitle, nil];
    
    alertView.alertType = ZDAlertTypeNormal;
    
    alertView.buttonClickBlock = ^(NSInteger buttonIndex){
        if (buttonIndex == 0)
        {
            if (cancelBlock) {
                cancelBlock(buttonIndex);
            }
        }
        else if (buttonIndex == 1)
        {
            if (otherBlock) {
                otherBlock(buttonIndex);
            }
        }
    };
    
    [alertView show];
}
//不定按钮
+ (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle buttonIndexBlock:(ZDAlertClickBlock)buttonIndexBlock otherButtonTitles:(NSString *)otherButtonTitles, ...
{
    if (!(title.length > 0) && message.length > 0) {
        title = @"";
    }
    ZDAlertView *alertView = [[ZDAlertView alloc] initWithTitle:title message:message cancelButtonTitle:cancelButtonTitle otherButtonTitle:nil];
    
    alertView.alertType = ZDAlertTypeNormal;
    alertView.buttonClickBlock = buttonIndexBlock;
    
    if (otherButtonTitles)
    {
        va_list args;//定义一个指向个数可变的参数列表指针
        va_start(args, otherButtonTitles);//得到第一个可变参数地址
        for (NSString *arg = otherButtonTitles; arg != nil; arg = va_arg(args, NSString *))
        {
            [alertView addButtonWithTitle:arg];
        }
        va_end(args);//置空指针
    }
    
    [alertView show];
}

//2.无按钮toast
+ (void)showToastViewWithTitle:(NSString *)title message:(NSString *)message duration:(NSTimeInterval)duration dismissCompletion:(ZDAlertClickBlock)dismissCompletion
{
    if (!(title.length > 0) && message.length > 0) {
        title = @"";
    }
    ZDAlertView *toastView = [[ZDAlertView alloc] initWithTitle:title message:message cancelButtonTitle:nil otherButtonTitle:nil];
    
    toastView.alertType = ZDAlertTypeToast;
    
    toastView.completionBlock = ^(NSInteger buttonIndex){
        if (buttonIndex == 0)
        {
            if (dismissCompletion) {
                dismissCompletion(buttonIndex);
            }
        }
    };
    
    [toastView show];
    
    duration = duration > 0 ? duration : ZDToastShowDurationDefault;
    [toastView performSelector:@selector(dismissToastView:) withObject:toastView afterDelay:duration];
}

- (void)dismissToastView:(UIAlertView *)toastView
{
    [toastView dismissWithClickedButtonIndex:0 animated:YES];
}

//3.文字HUD
+ (void)showTextHUDWithTitle:(NSString *)title message:(NSString *)message
{
    if (!(title.length > 0) && message.length > 0) {
        title = @"";
    }
    ZDAlertView *textHUD = [ZDAlertView sharedCommonHUDWithHUDType:ZDAlertHUDTypeTextOnly];
    
    textHUD.title = title;
//    [textHUD setTintColor:[UIColor whiteColor]];
//    textHUD.backgroundColor = [UIColor blackColor];
    textHUD.message = message;
    //    textHUD.delegate = nil;
    
    [textHUD show];
}

//4.loadHUD
+ (void)showLoadingHUDWithTitle:(NSString *)title message:(NSString *)message
{
    if (!(title.length > 0) && message.length > 0) {
        title = @"";
    }
    ZDAlertView *loadingHUD = [ZDAlertView sharedCommonHUDWithHUDType:ZDAlertHUDTypeLoading];
    
    loadingHUD.title = title;
    loadingHUD.message = message;
    
    [loadingHUD show];
}

//5.progressHUD
+ (void)showProgressHUDWithTitle:(NSString *)title message:(NSString *)message
{
    if (!(title.length > 0) && message.length > 0) {
        title = @"";
    }
    ZDAlertView *alertHUD = [ZDAlertView sharedCommonHUDWithHUDType:ZDAlertHUDTypeProgress];
    
    alertHUD.title = title;
    alertHUD.message = message;
    
    [alertHUD show];
}
+ (void)setHUDProgress:(float)progress
{
    ZDAlertView *alertHUD = [ZDAlertView sharedCommonHUD];
    [alertHUD.progressView setProgress:progress animated:YES];
    
    if (progress >= 1.0) {
        [alertHUD.progressView setProgress:1];
        //        [alertHUD dismissWithClickedButtonIndex:0 animated:YES];
    }
}

//6.HUD公用
+ (void)setHUDSuccessStateWithTitle:(NSString *)title message:(NSString *)message
{
    ZDAlertView *alertHUD = [ZDAlertView sharedCommonHUD];
    alertHUD.title = title;
    alertHUD.message = message;
    
    switch (alertHUD.alertHUDType)
    {
        case ZDAlertHUDTypeTextOnly:
            break;
        case ZDAlertHUDTypeLoading:
        {
            [alertHUD.indicatorView stopAnimating];
            if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
            {
                [alertHUD setValue:nil forKey:ZDAlertViewAccessoryViewKey];
            }
            else
            {
                [alertHUD.indicatorView removeFromSuperview];
            }
            alertHUD.indicatorView = nil;
            break;
        }
        case ZDAlertHUDTypeProgress:
        {
            [alertHUD.progressView setProgress:1 animated:YES];
            break;
        }
    }
}
+ (void)setHUDFailStateWithTitle:(NSString *)title message:(NSString *)message
{
    ZDAlertView *alertHUD = [ZDAlertView sharedCommonHUD];
    alertHUD.title = title;
    alertHUD.message = message;
    
    switch (alertHUD.alertHUDType)
    {
        case ZDAlertHUDTypeTextOnly:
            break;
        case ZDAlertHUDTypeLoading:
        {
            [alertHUD.indicatorView stopAnimating];
            if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
            {
                [alertHUD setValue:nil forKey:ZDAlertViewAccessoryViewKey];
            }
            else
            {
                [alertHUD.indicatorView removeFromSuperview];
            }
            alertHUD.indicatorView = nil;
            break;
        }
        case ZDAlertHUDTypeProgress:
        {
            [alertHUD.progressView setProgress:0 animated:YES];
            break;
        }
    }
}
+ (void)dismissHUD
{
    ZDAlertView *alertHUD = [ZDAlertView sharedCommonHUD];
    switch (alertHUD.alertHUDType)
    {
        case ZDAlertHUDTypeTextOnly:
            break;
        case ZDAlertHUDTypeLoading:
        {
            [alertHUD.indicatorView stopAnimating];
            alertHUD.indicatorView = nil;
            break;
        }
        case ZDAlertHUDTypeProgress:
            break;
    }
    [alertHUD dismissWithClickedButtonIndex:0 animated:YES];
}


#pragma mark - Delegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
{
    if (self.buttonClickBlock) {
        self.buttonClickBlock(buttonIndex);
    }
    self.buttonClickBlock = NULL;//解除闭环
}

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if (self.completionBlock) {
        self.completionBlock(buttonIndex);
    }
    self.completionBlock = NULL;//解除闭环
    
    switch (self.alertType)
    {
        case ZDAlertTypeNormal:
            break;
            
        case ZDAlertTypeToast:
        {
            //清理performSelector，防止意外情况下的内存泄漏
            [NSObject cancelPreviousPerformRequestsWithTarget:alertView selector:@selector(dismissToastView:) object:alertView];
            break;
        }
        case ZDAlertTypeHUD:
        {
            //清理static
            [ZDAlertView clearCommonHUD];
            break;
        }
    }
}


@end
